#!/usr/bin/python
# -*- coding: utf-8 -*-

'''
Created on 28/03/2011

@author: daniel
@contact: cdaniel.py@gmail.com
@summary : Clase de manejo de interaccion con base de datos SQL SERVER
'''

#importamos los modulos necesarios
import pymssql as libreria
from CdgPyPersistencia.bases.ConectorBase import ConectorBase


class SqlServerUtiles(ConectorBase):
    '''
    clase de manejo de interaccion con base de datos SQL SERVER
    '''
    
    NOMBRE_CLASE = "SqlServerUtiles"
    
    __oCursor    = libreria.Cursor
    
    
    
    def __init__(self, cUsuarioParam, cContrasenaParam, cServidorParam
                        , cCatalogoParam):
        '''
        inicializador de la clase
        '''
        
        #inicializamos la clase base
        super(SqlServerUtiles, self).__init__(cUsuarioParam, cContrasenaParam, cServidorParam
                                              , cCatalogoParam, 1433, "")
        
    
    
    def lConectar(self):
        '''Metodo de conexion al motor de base de datos'''
        
        NOMBRE_METODO = "lConectar() "
        
        #resultado por defecto
        lResultado = [0, NOMBRE_METODO + " no Ejecutado"]
        
        #intentamos abrir la conexion
        try:
            self.__oConexion = libreria.connect(user = self._cUsuario, password = self._cContrasena
                                               , host = self._cServidor, database = self._cCatalogo
                                               , timeout = 60, login_timeout = 30)
            
            self.__oCursor   = self.__oConexion.cursor()
            
            #resultado del metodo - #imprimimos la representacion de la conexion
            lResultado = [1, self.__str__()]
            
        except BaseException, oError:
            #en caso de error
            lResultado = [-1, NOMBRE_METODO + str(oError)]
            
        
        #devolvemos el resultado del metodo
        return lResultado
        
    
    
    def lDesconectar(self):
        '''Metodo de desconexion del motor de base de datos'''
        
        NOMBRE_METODO = "lDesconectar() "
        
        #resultado por defecto
        lResultado = [0, NOMBRE_METODO + " no Ejecutado"]
        
        #intentamos cerrar la conexion
        try:
            self.__oConexion.close()
            
            #resultado del metodo
            lResultado = [1, "Ok"]
            
        except BaseException, oError:
            #en caso de error
            lResultado = [-1, NOMBRE_METODO + str(oError)]
            
        
        #devolvemos el resultado del metodo
        return lResultado
        
    
    
    def lGet_cursor(self):
        '''Devuelve un cursor'''
        
        NOMBRE_METODO = "lGet_cursor() "
        
        #resultado por defecto
        lResultado = [0, NOMBRE_METODO + " no Ejecutado"]
        
        #intentamos abrir el cursor
        try:
            #establecemos el resultado
            lResultado = [1, self.__oConexion.cursor()]
            
        except BaseException, oError:
            #en caso de error
            lResultado = [-1, NOMBRE_METODO + str(oError)]
            
        
        #devolvemos el resultado del metodo
        return lResultado
        
    
    
    def lEjecutar_sentencia(self, cSentenciaSQL, dicValores):
        '''ejecuta una sentencia y devuelve el resultado de la ejecucion'''
        
        NOMBRE_METODO = "lEjecutar_sentencia() "
        
        #resultado por defecto
        lResultado = [0, NOMBRE_METODO + " no Ejecutado"]
        
        #intentamos ejecutar la sentencia sql
        try:
            self.__oCursor.execute(cSentenciaSQL, dicValores)
            
            #resultado del metodo
            lResultado = [1, "Ok"]
            
        except BaseException, oError:
            #en caso de error
            lResultado = [-1, NOMBRE_METODO + str(oError)]
            
        
        #devolvemos el resultado del metodo
        return lResultado
        
    
    
    def lEjecutar_consulta(self, cConsultaSQL, dicValores):
        '''ejecuta una consulta y devuelve el resultado de la ejecucion'''
        
        NOMBRE_METODO = "lEjecutar_consulta() "
        
        #resultado por defecto
        lResultado = [0, NOMBRE_METODO + " no Ejecutado"]
        
        #intentamos ejecutar la sentencia sql
        try:
            self.__oCursor.execute(cConsultaSQL, dicValores)
            
            #recuperamos todas las filas
            __aFilas = self.__oCursor.fetchall()
            
            #si hay filas devueltas
            if len(__aFilas) > 0:
                #resultado del metodo
                lResultado = [1, __aFilas]
                
            else:
                #sino
                lResultado = [0, self.NO_HAY_FILAS_DEVUELTAS]
                
            
        except BaseException, oError:
            #en caso de error
            lResultado = [-1, NOMBRE_METODO + str(oError)]
            
        
        #devolvemos el resultado del metodo
        return lResultado
        
    
    
    def lEjecutar_procedimiento(self, cProcedimiento, dicParametros):
        '''ejecuta el procedimiento y devuelve el resultado de la ejecucion'''
        
        NOMBRE_METODO = "lEjecutar_procedimiento() "
        
        #resultado por defecto
        lResultado = [0, NOMBRE_METODO + " no Ejecutado"]
        
        #intentamos ejecutar la sentencia sql
        try:
            #funciona solo con la version 2.0 del conector
            #self.__oCursor.callproc(cProcedimiento, dicParametros)
            
            print cProcedimiento % dicParametros
            
            lResultado = self.lEjecutar_sentencia(cProcedimiento, dicParametros)
            
            if lResultado[0] == 1:
                #resultado del metodo
                lResultado = [1, "Ok"]
                
            
        except BaseException, oError:
            #en caso de error
            lResultado = [-1, NOMBRE_METODO + str(oError)]
            
        
        #devolvemos el resultado del metodo
        return lResultado
        
    
    
    def Set_autocomit(self, bAutocommit):
        '''Establece el modo de confirmacion de transacciones'''
        
        NOMBRE_METODO = "Set_autocomit() "
        
        try:
            self.__oConexion.autocommit = bAutocommit
            
        except BaseException, oError:
            #en caso de error
            print "Error " + NOMBRE_METODO + str(oError)
            
        
        pass;
        
    
    
    def lIniciar_transaccion(self):
        '''Inicia una Transaccion'''
        
        NOMBRE_METODO = "lIniciar_transaccion() "
        
        #resultado por defecto
        lResultado = [0, NOMBRE_METODO + " no Ejecutado"]
        
        #intentamos iniciar la transaccion
        try:
            self.__oConexion.begin()
            
            #resultado del metodo
            lResultado = [1, "Ok"]
            
        except BaseException, oError:
            #en caso de error
            lResultado = [-1, NOMBRE_METODO + str(oError)]
            
        
        #devolvemos el resultado del metodo
        return lResultado
        
    
    
    def lConfirmar_transaccion(self):
        '''Confirma una Transaccion'''
        
        NOMBRE_METODO = "lConfirmar_transaccion() "
        
        #resultado por defecto
        lResultado = [0, NOMBRE_METODO + " no Ejecutado"]
        
        #intentamos confirmar la transaccion
        try:
            self.__oConexion.commit()
            
            #resultado del metodo
            lResultado = [1, "Ok"]
            
        except BaseException, oError:
            #en caso de error
            lResultado = [-1, NOMBRE_METODO + str(oError)]
            
        
        #devolvemos el resultado del metodo
        return lResultado
        
    
    
    def lRevertir_transaccion(self):
        '''Revierta una Transaccion'''
        
        NOMBRE_METODO = "lRevertir_transaccion() "
        
        #resultado por defecto
        lResultado = [0, NOMBRE_METODO + " no Ejecutado"]
        
        #intentamos revertir la transaccion
        try:
            self.__oConexion.rollback()
            
            #resultado del metodo
            lResultado = [1, "Ok"]
            
        except BaseException, oError:
            #en caso de error
            lResultado = [-1, NOMBRE_METODO + str(oError)]
            
        
        #devolvemos el resultado del metodo
        return lResultado
        
    
    


if __name__ == "__main__":
    
    oConector = SqlServerUtiles("tester", "tester123", ".\\sqlexpress", "tester", "")
    
    lResultado = oConector.lConectar()
    
    if lResultado[0] == 1:
        
        #lResultado = oConector.lEjecutar_consulta("select * from persona", {})
        
        lResultado = oConector.lEjecutar_procedimiento("SP_CAMBIAR_ESTADO %s", "soltero")
        
        #lResultado = oConector.lEjecutar_sentencia("INSERT INTO [persona] VALUES(%s,%s,%d,%d,%s,%s,%s,%s,%s)" 
        #                                            , ('isabel','sosa',2365478,1,'f','1978-04-03','av. humaita','0981 427 569','soltero'))
        
        if lResultado[0] == 1:
            oConector.lConfirmar_transaccion()
            for fila in lResultado[1]:
                print fila
                
        else:
            print lResultado[1]
        
    else:
        print lResultado[1]
        
    
    
